﻿using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Windows;

namespace GaleSong
{
    /// <summary>
    ///     Native methods.
    /// </summary>
    [SuppressUnmanagedCodeSecurity]
    internal static class NativeMethods
    {
        #region Field

        internal const int MA_ACTIVATE = 1;
        internal const int MA_ACTIVATEANDEAT = 2;
        internal const int MA_NOACTIVATE = 3;
        internal const int MA_NOACTIVATEANDEAT = 4;

        internal const int SWP_NOACTIVATE = 0x10;
        internal const int SWP_NOMOVE = 2;
        internal const int SWP_NOSIZE = 1;
        internal const int SWP_NOZORDER = 0x0004;
        internal const int SWP_FRAMECHANGED = 0x0020;

        internal const int WS_CHILD = 0x40000000;
        internal const int WS_VISIBLE = 0x10000000;
        internal const int WS_VSCROLL = 0x00200000;
        internal const int WS_BORDER = 0x00800000;
        internal const int WS_EX_NOACTIVATE = 0x8000000;
        internal const int WS_EX_DLGMODALFRAME = 0x0001;
        internal const int WS_DLGFRAME = 0x00400000;
        internal const int WS_SYSMENU = 0x80000;
        internal const int WS_MINIMIZEBOX = 0x20000;
        internal const int WS_MAXIMIZEBOX = 0x10000;

        internal const int GWL_STYLE = -16;
        internal const int GWL_EXSTYLE = -20;
        internal const int LBS_NOTIFY = 0x00000001;
        internal const int HOST_ID = 0x00000002;
        internal const int LISTBOX_ID = 0x00000001;
        internal const int HWND_NOTOPMOST = -2;
        private static int _dpi;

        #endregion

        #region Method

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/aa969518%28v=vs.85%29.aspx</devdoc>
        [DllImport("dwmapi", PreserveSig = false, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DwmIsCompositionEnabled();

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/aa969512%28v=vs.85%29.aspx</devdoc>
        [DllImport("dwmapi", PreserveSig = true, CallingConvention = CallingConvention.Winapi, ExactSpelling = true)]
        [return: MarshalAs(UnmanagedType.Error)]
        internal static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, [In] ref MARGINS pMarInset);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/aa969524%28v=vs.85%29.aspx</devdoc>
        [DllImport("dwmapi", PreserveSig = true, CallingConvention = CallingConvention.Winapi, ExactSpelling = true)]
        internal static extern int DwmSetWindowAttribute([In] IntPtr hwnd, [In] int attr, [In] ref int attrValue,
            [In] int attrSize);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms633572%28v=vs.85%29.aspx</devdoc>
        [DllImport("user32", CallingConvention = CallingConvention.Winapi)]
        internal static extern IntPtr DefWindowProc([In] IntPtr hwnd, [In] int msg, [In] IntPtr wParam,
            [In] IntPtr lParam);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/dd144901%28v=VS.85%29.aspx</devdoc>
        [DllImport("user32", EntryPoint = "GetMonitorInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetMonitorInfo([In] IntPtr hMonitor, [Out] MONITORINFO lpmi);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/dd145064%28v=VS.85%29.aspx</devdoc>
        [DllImport("user32")]
        internal static extern IntPtr MonitorFromWindow([In] IntPtr handle, [In] int flags);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx</devdoc>
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy,
            uint uFlags);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms647486%28v=vs.85%29.aspx</devdoc>
        [DllImport("user32", CharSet = CharSet.Unicode, ExactSpelling = true, EntryPoint = "LoadStringW",
            SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        internal static extern int LoadString([In] [Optional] IntPtr hInstance, [In] uint uID,
            [Out] StringBuilder lpBuffer, [In] int nBufferMax);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms633528(v=vs.85).aspx</devdoc>
        [DllImport("user32", CharSet = CharSet.Auto, ExactSpelling = true)]
        internal static extern bool IsWindow([In] [Optional] IntPtr hWnd);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms647985(v=vs.85).aspx</devdoc>
        [DllImport("user32")]
        internal static extern IntPtr GetSystemMenu([In] IntPtr hWnd, [In] bool bRevert);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms648003(v=vs.85).aspx</devdoc>
        [DllImport("user32")]
        internal static extern uint TrackPopupMenuEx([In] IntPtr hmenu, [In] uint fuFlags, [In] int x, [In] int y,
            [In] IntPtr hwnd, [In] [Optional] IntPtr lptpm);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms644944(v=vs.85).aspx</devdoc>
        [DllImport("user32", EntryPoint = "PostMessage", SetLastError = true)]
        private static extern bool _PostMessage([In] [Optional] IntPtr hWnd, [In] uint Msg, [In] IntPtr wParam,
            [In] IntPtr lParam);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms648390(v=vs.85).aspx</devdoc>
        [DllImport("user32")]
        internal static extern bool GetCursorPos([Out] out Win32Point pt);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms646258(v=vs.85).aspx</devdoc>
        [DllImport("user32", CharSet = CharSet.Auto, ExactSpelling = true)]
        internal static extern int GetDoubleClickTime();

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx</devdoc>
        [DllImport("kernel32", CharSet = CharSet.Unicode, ExactSpelling = true, EntryPoint = "LoadLibraryW",
            SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        internal static extern IntPtr LoadLibrary([In] [MarshalAs(UnmanagedType.LPWStr)] string lpFileName);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms683152%28v=vs.85%29.aspx</devdoc>
        [DllImport("kernel32", CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool FreeLibrary([In] IntPtr hModule);

        [DllImport("user32.dll", EntryPoint = "SetClassLong")]
        internal static extern uint SetClassLongPtr32(IntPtr hWnd, int nIndex, uint dwNewLong);

        [DllImport("user32.dll", EntryPoint = "SetClassLongPtr")]
        internal static extern IntPtr SetClassLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("gdi32.dll")]
        internal static extern IntPtr CreateSolidBrush(int crColor);

        [DllImport("gdi32.dll")]
        internal static extern bool DeleteObject(IntPtr hObject);

        [DllImport("user32.dll")]
        internal static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);

        [DllImport("user32.dll")]
        internal static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);

        /// <devdoc>http://msdn.microsoft.com/en-us/library/windows/desktop/ms647636(v=vs.85).aspx</devdoc>
        [DllImport("user32.dll")]
        internal static extern uint EnableMenuItem(IntPtr hMenu, uint itemId, uint uEnable);

        internal static void PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam)
        {
            if(!_PostMessage(hWnd, Msg, wParam, lParam))
            {
                throw new Win32Exception();
            }
        }

        internal static int GET_X_LPARAM(IntPtr lParam)
        {
            return LOWORD(lParam.ToInt32());
        }

        internal static int GET_Y_LPARAM(IntPtr lParam)
        {
            return HIWORD(lParam.ToInt32());
        }

        private static int HIWORD(int i)
        {
            return (short)(i >> 16);
        }

        private static int LOWORD(int i)
        {
            return (short)(i & 0xFFFF);
        }


        /// <summary>
        ///     Converts the DI uto pixel.
        /// </summary>
        /// <param name="diu">The diu.</param>
        /// <returns></returns>
        public static int ConvertDIUtoPixel(double diu)
        {
            return (int)((diu * DPI) / 96.0);
        }

        /// <summary>
        ///     Converts the pixels to DI pixels.
        /// </summary>
        /// <param name="pixels">The pixels.</param>
        /// <returns></returns>
        public static double ConvertPixelsToDIPixels(int pixels)
        {
            return ((pixels * 96.0) / DPI);
        }

        /// <summary>
        ///     Creates the round rect RGN.
        /// </summary>
        /// <param name="x1">The x1.</param>
        /// <param name="y1">The y1.</param>
        /// <param name="x2">The x2.</param>
        /// <param name="y2">The y2.</param>
        /// <param name="x3">The x3.</param>
        /// <param name="y3">The y3.</param>
        /// <returns></returns>
        [DllImport("gdi32.dll")]
        internal static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3);

        /// <summary>
        ///     Gets the cursor pos.
        /// </summary>
        /// <returns></returns>
        internal static Point GetCursorPos()
        {
            NativePoint mouse;
            GetCursorPos(out mouse);
            return new Point(mouse.X, mouse.Y);
        }

        /// <summary>
        ///     Gets the cursor pos.
        /// </summary>
        /// <param name="lpPoint">The lp point.</param>
        /// <returns></returns>
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool GetCursorPos(out NativePoint lpPoint);

        /// <summary>
        ///     Gets the DC.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern IntPtr GetDC(HandleRef hWnd);

        /// <summary>
        ///     Gets the device caps.
        /// </summary>
        /// <param name="hDC">The h DC.</param>
        /// <param name="nIndex">Index of the n.</param>
        /// <returns></returns>
        [DllImport("gdi32.dll")]
        private static extern int GetDeviceCaps(HandleRef hDC, int nIndex);

        /// <summary>
        ///     Gets the window rect.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <returns></returns>
        internal static Rect GetWindowRect(IntPtr hWnd)
        {
            RECT rect;
            GetWindowRect(hWnd, out rect);
            return new Rect(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
        }

        /// <summary>
        ///     Gets the window rect.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="lpRect">The lp rect.</param>
        /// <returns></returns>
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

        internal static void MoveWindow(IntPtr hWnd, Rect rect)
        {
            MoveWindow(hWnd, (int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height, true);
        }

        /// <summary>
        ///     Moves the window.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="x">The X.</param>
        /// <param name="y">The Y.</param>
        /// <param name="nWidth">Width of the n.</param>
        /// <param name="nHeight">Height of the n.</param>
        /// <param name="bRepaint">if set to <c>true</c> [b repaint].</param>
        /// <returns></returns>
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight,
            [MarshalAs(UnmanagedType.Bool)] bool bRepaint);

        /// <summary>
        ///     Releases the DC.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="hDC">The h DC.</param>
        [DllImport("user32.dll")]
        private static extern void ReleaseDC(HandleRef hWnd, HandleRef hDC);

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool ScreenToClient(IntPtr hWnd, ref NativePoint lpPoint);

        /// <summary>
        ///     Sets the window pos.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="hwndInsertAfter">The HWND insert after.</param>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="cx">The cx.</param>
        /// <param name="cy">The cy.</param>
        /// <param name="wFlags">The w flags.</param>
        /// <returns></returns>
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool SetWindowPos(IntPtr hWnd, int hwndInsertAfter, int x, int y, int cx, int cy,
            int wFlags);

        /// <summary>
        ///     Sets the window RGN.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="hRgn">The h RGN.</param>
        /// <param name="bRedraw">The b redraw.</param>
        [DllImport("user32.dll")]
        internal static extern void SetWindowRgn(IntPtr hWnd, IntPtr hRgn, int bRedraw);

        /// <summary>
        ///     Switches to this window.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        [DllImport("user32.dll")]
        internal static extern void SwitchToThisWindow(IntPtr hWnd);

        /// <summary>
        ///     Sets the window long.
        /// </summary>
        /// <param name="window">The window.</param>
        /// <param name="index">The index.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern int SetWindowLong(IntPtr window, int index, int value);

        /// <summary>
        ///     Gets the window long.
        /// </summary>
        /// <param name="window">The window.</param>
        /// <param name="index">The index.</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern int GetWindowLong(IntPtr window, int index);

        [StructLayout(LayoutKind.Sequential)]
        internal struct Win32Point
        {
            public readonly Int32 X;
            public readonly Int32 Y;
        };

        #endregion

        #region Property

        public static int DPI
        {
            get
            {
                if(_dpi == 0)
                {
                    var desktopHwnd = new HandleRef(null, IntPtr.Zero);
                    var desktopDC = new HandleRef(null, GetDC(desktopHwnd));
                    _dpi = GetDeviceCaps(desktopDC, 0x58);
                    ReleaseDC(desktopHwnd, desktopDC);
                }
                return _dpi;
            }
        }

        #endregion

        [StructLayout(LayoutKind.Sequential)]
        public struct MARGINS
        {
            public int leftWidth;
            public int rightWidth;
            public int topHeight;
            public int bottomHeight;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct MINMAXINFO
        {
            public POINT ptReserved;
            public POINT ptMaxSize;
            public POINT ptMaxPosition;
            public POINT ptMinTrackSize;
            public POINT ptMaxTrackSize;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal class MONITORINFO
        {
            public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
            public RECT rcMonitor = new RECT();
            public RECT rcWork = new RECT();
            public int dwFlags;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct NativePoint
        {
            public int X;
            public int Y;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                X = x;
                Y = y;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RECT
        {
            public readonly int Left;
            public int Top;
            public int Right;
            public int Bottom;
            public static readonly RECT Empty;

            public int Width
            {
                get { return Math.Abs(Right - Left); }
            }

            public int Height
            {
                get { return (Bottom - Top); }
            }

            public RECT(int left, int top, int right, int bottom)
            {
                Left = left;
                Top = top;
                Right = right;
                Bottom = bottom;
            }

            public RECT(RECT rcSrc)
            {
                Left = rcSrc.Left;
                Top = rcSrc.Top;
                Right = rcSrc.Right;
                Bottom = rcSrc.Bottom;
            }

            public bool IsEmpty
            {
                get
                {
                    if(Left < Right)
                    {
                        return (Top >= Bottom);
                    }
                    return true;
                }
            }

            public override string ToString()
            {
                if(this == Empty)
                {
                    return "RECT {Empty}";
                }
                return
                    string.Concat(new object[]
                    { "RECT { left : ", Left, " / top : ", Top, " / right : ", Right, " / bottom : ", Bottom, " }" });
            }

            public override bool Equals(object obj)
            {
                return ((obj is Rect) && (this == (RECT)obj));
            }

            public override int GetHashCode()
            {
                return (((Left.GetHashCode() + Top.GetHashCode()) + Right.GetHashCode()) + Bottom.GetHashCode());
            }

            public static bool operator ==(RECT rect1, RECT rect2)
            {
                return ((((rect1.Left == rect2.Left) && (rect1.Top == rect2.Top)) && (rect1.Right == rect2.Right)) &&
                        (rect1.Bottom == rect2.Bottom));
            }

            public static bool operator !=(RECT rect1, RECT rect2)
            {
                return !(rect1 == rect2);
            }

            static RECT()
            {
                Empty = new RECT();
            }
        }

        [Serializable]
        [StructLayout(LayoutKind.Sequential)]
        public struct WINDOWPLACEMENT
        {
            public int length;
            public int flags;
            public int showCmd;
            public POINT minPosition;
            public POINT maxPosition;
            public RECT normalPosition;
        }
    }

    /// <summary>
    ///     WindowMessage
    /// </summary>
    internal enum WindowMessage : uint
    {
        TPM_LEFTBUTTON = 0x0,
        TPM_RETURNCMD = 0x0100,

        WM_ACTIVATE = 6,
        WM_ACTIVATEAPP = 0x1c,
        WM_AFXFIRST = 0x360,
        WM_AFXLAST = 0x37f,
        WM_APP = 0x8000,
        WM_APPCOMMAND = 0x319,
        WM_ASKCBFORMATNAME = 780,
        WM_CANCELJOURNAL = 0x4b,
        WM_CANCELMODE = 0x1f,
        WM_CAPTURECHANGED = 0x215,
        WM_CHANGECBCHAIN = 0x30d,
        WM_CHANGEUISTATE = 0x127,
        WM_CHAR = 0x102,
        WM_CHARTOITEM = 0x2f,
        WM_CHILDACTIVATE = 0x22,
        WM_CLEAR = 0x303,
        WM_CLOSE = 0x10,
        WM_COMMAND = 0x111,
        WM_COMMNOTIFY = 0x44,
        WM_COMPACTING = 0x41,
        WM_COMPAREITEM = 0x39,
        WM_CONTEXTMENU = 0x7b,
        WM_COPY = 0x301,
        WM_COPYDATA = 0x4a,
        WM_CREATE = 1,
        WM_CTLCOLOR = 0x19,
        WM_CTLCOLORBTN = 0x135,
        WM_CTLCOLORDLG = 310,
        WM_CTLCOLOREDIT = 0x133,
        WM_CTLCOLORLISTBOX = 0x134,
        WM_CTLCOLORMSGBOX = 0x132,
        WM_CTLCOLORSCROLLBAR = 0x137,
        WM_CTLCOLORSTATIC = 0x138,
        WM_CUT = 0x300,
        WM_DEADCHAR = 0x103,
        WM_DELETEITEM = 0x2d,
        WM_DESTROY = 2,
        WM_DESTROYCLIPBOARD = 0x307,
        WM_DEVICECHANGE = 0x219,
        WM_DEVMODECHANGE = 0x1b,
        WM_DISPLAYCHANGE = 0x7e,
        WM_DRAWCLIPBOARD = 0x308,
        WM_DRAWITEM = 0x2b,
        WM_DROPFILES = 0x233,
        WM_DWMCOLORIZATIONCOLORCHANGED = 800,
        WM_DWMCOMPOSITIONCHANGED = 0x31e,
        WM_DWMNCRENDERINGCHANGED = 0x31f,
        WM_DWMSENDICONICLIVEPREVIEWBITMAP = 0x326,
        WM_DWMSENDICONICTHUMBNAIL = 0x323,
        WM_DWMWINDOWMAXIMIZEDCHANGE = 0x321,
        WM_ENABLE = 10,
        WM_ENDSESSION = 0x16,
        WM_ENTERIDLE = 0x121,
        WM_ENTERMENULOOP = 0x211,
        WM_ENTERSIZEMOVE = 0x231,
        WM_ERASEBKGND = 20,
        WM_EXITMENULOOP = 530,
        WM_EXITSIZEMOVE = 0x232,
        WM_FONTCHANGE = 0x1d,
        WM_GETDLGCODE = 0x87,
        WM_GETFONT = 0x31,
        WM_GETHOTKEY = 0x33,
        WM_GETICON = 0x7f,
        WM_GETMINMAXINFO = 0x24,
        WM_GETOBJECT = 0x3d,
        WM_GETTEXT = 13,
        WM_GETTEXTLENGTH = 14,
        WM_HANDHELDFIRST = 0x358,
        WM_HANDHELDLAST = 0x35f,
        WM_HELP = 0x53,
        WM_HOTKEY = 0x312,
        WM_HSCROLL = 0x114,
        WM_HSCROLLCLIPBOARD = 0x30e,
        WM_ICONERASEBKGND = 0x27,
        WM_IME_CHAR = 0x286,
        WM_IME_COMPOSITION = 0x10f,
        WM_IME_COMPOSITIONFULL = 0x284,
        WM_IME_CONTROL = 0x283,
        WM_IME_ENDCOMPOSITION = 270,
        WM_IME_KEYDOWN = 0x290,
        WM_IME_KEYLAST = 0x10f,
        WM_IME_KEYUP = 0x291,
        WM_IME_NOTIFY = 0x282,
        WM_IME_REQUEST = 0x288,
        WM_IME_SELECT = 0x285,
        WM_IME_SETCONTEXT = 0x281,
        WM_IME_STARTCOMPOSITION = 0x10d,
        WM_INITDIALOG = 0x110,
        WM_INITMENU = 0x116,
        WM_INITMENUPOPUP = 0x117,
        WM_INPUT = 0xff,
        WM_INPUTLANGCHANGE = 0x51,
        WM_INPUTLANGCHANGEREQUEST = 80,
        WM_KEYDOWN = 0x100,
        WM_KEYFIRST = 0x100,
        WM_KEYLAST = 0x108,
        WM_KEYUP = 0x101,
        WM_KILLFOCUS = 8,
        WM_LBUTTONDBLCLK = 0x203,
        WM_LBUTTONDOWN = 0x201,
        WM_LBUTTONUP = 0x202,
        WM_MBUTTONDBLCLK = 0x209,
        WM_MBUTTONDOWN = 0x207,
        WM_MBUTTONUP = 520,
        WM_MDIACTIVATE = 0x222,
        WM_MDICASCADE = 0x227,
        WM_MDICREATE = 0x220,
        WM_MDIDESTROY = 0x221,
        WM_MDIGETACTIVE = 0x229,
        WM_MDIICONARRANGE = 0x228,
        WM_MDIMAXIMIZE = 0x225,
        WM_MDINEXT = 0x224,
        WM_MDIREFRESHMENU = 0x234,
        WM_MDIRESTORE = 0x223,
        WM_MDISETMENU = 560,
        WM_MDITILE = 550,
        WM_MEASUREITEM = 0x2c,
        WM_MENUCHAR = 0x120,
        WM_MENUSELECT = 0x11f,
        WM_MOUSEACTIVATE = 0x21,
        WM_MOUSEFIRST = 0x200,
        WM_MOUSEHOVER = 0x2a1,
        WM_MOUSEHWHEEL = 0x20e,
        WM_MOUSELAST = 0x20e,
        WM_MOUSELEAVE = 0x2a3,
        WM_MOUSEMOVE = 0x200,
        WM_MOUSEQUERY = 0x9b,
        WM_MOUSEWHEEL = 0x20a,
        WM_MOVE = 3,
        WM_MOVING = 0x216,
        WM_NCACTIVATE = 0x86,
        WM_NCCALCSIZE = 0x83,
        WM_NCCREATE = 0x81,
        WM_NCDESTROY = 130,
        WM_NCHITTEST = 0x84,
        WM_NCLBUTTONDBLCLK = 0xa3,
        WM_NCLBUTTONDOWN = 0xa1,
        WM_NCLBUTTONUP = 0xa2,
        WM_NCMBUTTONDBLCLK = 0xa9,
        WM_NCMBUTTONDOWN = 0xa7,
        WM_NCMBUTTONUP = 0xa8,
        WM_NCMOUSELEAVE = 0x2a2,
        WM_NCMOUSEMOVE = 160,
        WM_NCPAINT = 0x85,
        WM_NCRBUTTONDBLCLK = 0xa6,
        WM_NCRBUTTONDOWN = 0xa4,
        WM_NCRBUTTONUP = 0xa5,
        WM_NCXBUTTONDBLCLK = 0xad,
        WM_NCXBUTTONDOWN = 0xab,
        WM_NCXBUTTONUP = 0xac,
        WM_NEXTDLGCTL = 40,
        WM_NEXTMENU = 0x213,
        WM_NOTIFY = 0x4e,
        WM_NOTIFYFORMAT = 0x55,
        WM_NULL = 0,
        WM_PAINT = 15,
        WM_PAINTCLIPBOARD = 0x309,
        WM_PAINTICON = 0x26,
        WM_PALETTECHANGED = 0x311,
        WM_PALETTEISCHANGING = 0x310,
        WM_PARENTNOTIFY = 0x210,
        WM_PASTE = 770,
        WM_PENWINFIRST = 0x380,
        WM_PENWINLAST = 0x38f,
        WM_POWER = 0x48,
        WM_POWERBROADCAST = 0x218,
        WM_PRINT = 0x317,
        WM_PRINTCLIENT = 0x318,
        WM_QUERYDRAGICON = 0x37,
        WM_QUERYENDSESSION = 0x11,
        WM_QUERYNEWPALETTE = 0x30f,
        WM_QUERYOPEN = 0x13,
        WM_QUERYUISTATE = 0x129,
        WM_QUEUESYNC = 0x23,
        WM_QUIT = 0x12,
        WM_RBUTTONDBLCLK = 0x206,
        WM_RBUTTONDOWN = 0x204,
        WM_RBUTTONUP = 0x205,
        WM_RENDERALLFORMATS = 0x306,
        WM_RENDERFORMAT = 0x305,
        WM_SETCURSOR = 0x20,
        WM_SETFOCUS = 7,
        WM_SETFONT = 0x30,
        WM_SETHOTKEY = 50,
        WM_SETICON = 0x80,
        WM_SETREDRAW = 11,
        WM_SETTEXT = 12,
        WM_SETTINGCHANGE = 0x1a,
        WM_SHOWWINDOW = 0x18,
        WM_SIZE = 5,
        WM_SIZECLIPBOARD = 0x30b,
        WM_SIZING = 0x214,
        WM_SPOOLERSTATUS = 0x2a,
        WM_STYLECHANGED = 0x7d,
        WM_STYLECHANGING = 0x7c,
        WM_SYNCPAINT = 0x88,
        WM_SYSCHAR = 0x106,
        WM_SYSCOLORCHANGE = 0x15,
        WM_SYSCOMMAND = 0x112,
        WM_SYSDEADCHAR = 0x107,
        WM_SYSKEYDOWN = 260,
        WM_SYSKEYUP = 0x105,
        WM_TABLET_ADDED = 0x2c8,
        WM_TABLET_DEFBASE = 0x2c0,
        WM_TABLET_DELETED = 0x2c9,
        WM_TABLET_FLICK = 0x2cb,
        WM_TABLET_MAXOFFSET = 0x20,
        WM_TABLET_QUERYSYSTEMGESTURESTATUS = 0x2cc,
        WM_TCARD = 0x52,
        WM_THEMECHANGED = 0x31a,
        WM_TIMECHANGE = 30,
        WM_TIMER = 0x113,
        WM_UNDO = 0x304,
        WM_UNINITMENUPOPUP = 0x125,
        WM_UPDATEUISTATE = 0x128,
        WM_USER = 0x400,
        WM_USERCHANGED = 0x54,
        WM_VKEYTOITEM = 0x2e,
        WM_VSCROLL = 0x115,
        WM_VSCROLLCLIPBOARD = 0x30a,
        WM_WINDOWPOSCHANGED = 0x47,
        WM_WINDOWPOSCHANGING = 70,
        WM_WININICHANGE = 0x1a,
        WM_WTSSESSION_CHANGE = 0x2b1,
        WM_XBUTTONDBLCLK = 0x20d,
        WM_XBUTTONDOWN = 0x20b,
        WM_XBUTTONUP = 0x20c
    }
}